package exam.file.controller;

import com.alibaba.fastjson.JSONObject;
import exam.common.Result;
import exam.file.domain.UFile;
import exam.file.service.UFileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Xiongx
 * @version 1.0
 * @date 2021/4/9 21:53
 * @since JDK 1.8
 *
 * 文件管理测试模块
 */
@RestController
@Slf4j
@Api(tags = {"文件管理模块"})
public class TestUFileController {

    private static String UPLOAD_PATH_PREFIX="upload";

    @Autowired
    private UFileService uFileService;

    @ResponseBody
    @RequestMapping(value="/multifileUpload",method= RequestMethod.POST)
    public JSONObject multifileUpload(MultipartFile file, HttpServletRequest request){
        if(file==null){
           return Result.errorObject("文件不存在");
        }
        //文件名
        String fileName = file.getOriginalFilename();
        //文件类型
        String type=file.getContentType();
        String realPath = new String("src/main/resources/" + UPLOAD_PATH_PREFIX);
        //文件大小
        Double size = Double.valueOf(String.valueOf(file.getSize()/1024*512)) ;

        File file1 = new File(realPath );
        if(!file1.isDirectory()){
            file1.mkdirs();
        }
        try {
            File dest = new File(file1.getAbsoluteFile() + File.separator+fileName);
            file.transferTo( dest ); //保存文件
            //文件路径
            String path=dest.getPath();
            UFile uFile=new UFile();
            uFile.builder().filename(fileName)
                    .fileType(type).realFileName(fileName).path(path)
                    .size(size).sizeType("MB");
            Boolean flag=uFileService.save(uFile);
            if(flag){
                return Result.successObject("上传成功");
            }
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Result.errorObject("上传出错");
    }

    @RequestMapping(value="/uploadFile",method={RequestMethod.POST})
    @ResponseBody
    public Map<String,Object> addImg(HttpServletRequest request, HttpServletResponse response){
        Map<String,Object> result= new HashMap<>();

        // 转型为MultipartHttpRequest：
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        // 获得文件：
        MultipartFile file= multipartRequest.getFile("file_data");
        //文件名
        String fileName = file.getOriginalFilename();
        //文件类型
        String type=file.getContentType();
        String realPath = new String("src/main/resources/" + UPLOAD_PATH_PREFIX);
        //文件大小
        Long size1=(file.getSize()/1024)/1024;
        Double size = Double.valueOf(String.valueOf(size1)) ;

        File file1 = new File(realPath );
        if(!file1.isDirectory()){
            file1.mkdirs();
        }
        try {
            File dest = new File(file1.getAbsoluteFile() + File.separator+fileName);
            file.transferTo( dest ); //保存文件
            //文件路径
            String path=dest.getPath();
            UFile uFile=UFile.builder().sizeType("m").size(size)
                    .fileType(type).realFileName(fileName).path(path)
                    .filename(fileName).build();
            Boolean flag=uFileService.save(uFile);
            if(flag){
                return Result.successObject("上传成功");
            }
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Result.errorObject("上传出错");

    }

    @RequestMapping("donload")
    @ApiModelProperty("文件下载")
    private JSONObject sendVideo(HttpServletRequest request, HttpServletResponse response,@ApiParam("文件id") @RequestParam("id") Integer id) throws FileNotFoundException, IOException {
        if(StringUtils.isEmpty(id)){
            return Result.errorObject("id不得为空");
        }
        UFile uFile=uFileService.getById(id);
        if(StringUtils.isEmpty(uFile)){
            return Result.errorObject("文件数据已过期");
        }
        File file = new File(uFile.getPath());
        RandomAccessFile randomFile = new RandomAccessFile(file, "r");//只读模式
        long contentLength = randomFile.length();
        String range = request.getHeader("Range");
        int start = 0, end = 0;
        if(range != null && range.startsWith("bytes=")){
            String[] values = range.split("=")[1].split("-");
            start = Integer.parseInt(values[0]);
            if(values.length > 1){
                end = Integer.parseInt(values[1]);
            }
        }
        int requestSize = 0;
        if(end != 0 && end > start){
            requestSize = end - start + 1;
        } else {
            requestSize = Integer.MAX_VALUE;
        }
        String fileName = URLEncoder.encode(file.getName(), "UTF-8");
        response.setContentType(uFile.getFileType());
        response.setHeader("Accept-Ranges", "bytes");
        response.setHeader("ETag", file.getName());
        response.addHeader("Content-Disposition", "form-data ; filename=" + fileName );
        response.setHeader("Last-Modified",uFile.getCreateTime().toString());
        //第一次请求只返回content length来让客户端请求多次实际数据
        if(range == null){
            response.setHeader("Content-length", contentLength + "");
        }else{
            //以后的多次以断点续传的方式来返回视频数据
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);//206
            long requestStart = 0, requestEnd = 0;
            String[] ranges = range.split("=");
            if(ranges.length > 1){
                String[] rangeDatas = ranges[1].split("-");
                requestStart = Integer.parseInt(rangeDatas[0]);
                if(rangeDatas.length > 1){
                    requestEnd = Integer.parseInt(rangeDatas[1]);
                }
            }
            long length = 0;
            if(requestEnd > 0){
                length = requestEnd - requestStart + 1;
                response.setHeader("Content-length", "" + length);
                response.setHeader("Content-Range", "bytes " + requestStart + "-" + requestEnd + "/" + contentLength);
            }else{
                length = contentLength - requestStart;
                response.setHeader("Content-length", "" + length);
                response.setHeader("Content-Range", "bytes "+ requestStart + "-" + (contentLength - 1) + "/" + contentLength);
            }
        }
        ServletOutputStream out = response.getOutputStream();
        int needSize = requestSize;
        randomFile.seek(start);
        while(needSize > 0){
            byte[] buffer = new byte[4096];
            int len = randomFile.read(buffer);
            if(needSize < buffer.length){
                out.write(buffer, 0, needSize);
            } else {
                out.write(buffer, 0, len);
                if(len < buffer.length){
                    break;
                }
            }
            needSize -= buffer.length;
        }
        randomFile.close();
        out.close();
        return Result.successObject("传输完成");
    }

}
